#include "stm32l0xx_hal.h"
#include "ADS8866.h"
#include "main.h"
#include "spi.h"
#include "delay.h"
#include "my_spi.h"
#include <stdio.h>
#if 0
#define TxData_Len 5
#define RxData_Len 5
uint8_t TxData[TxData_Len] = { 0 };
uint8_t RxData[RxData_Len] = { 0 };

#if USE_HARD_SPI

void stm32_ads8866_spi_init(struct ads8866_spi* priv_data)
{
	//MX_SPI1_Init();
}
ADS8866_StatusTypeDef stm32_ads8866_spi_transmit(struct ads8866_spi* priv_data,
												  uint8_t *pData,
												  uint16_t Size, 
												  uint32_t Timeout)
{
	ADS8866_StatusTypeDef status;
	status = (ADS8866_StatusTypeDef) HAL_SPI_Transmit((SPI_HandleTypeDef*)priv_data->private_data,
													 pData,
													 Size,
													 Timeout);
	return status;
}
ADS8866_StatusTypeDef stm32_ads8866_spi_receive(struct ads8866_spi* priv_data,
												uint8_t *pData,
												uint16_t Size,
												uint32_t Timeout)
{
	ADS8866_StatusTypeDef status;
	status = (ADS8866_StatusTypeDef) HAL_SPI_Receive((SPI_HandleTypeDef*)priv_data->private_data,
													pData,
													Size,
													Timeout);
	return status;
}
ADS8866_StatusTypeDef stm32_ads8866_spi_transmit_and_receive(struct ads8866_spi* priv_data,	
															 uint8_t *pTxData,
															 uint8_t *pRxData,
															 uint16_t Size,
														 	 uint32_t Timeout)
{
	ADS8866_StatusTypeDef status;
	status = (ADS8866_StatusTypeDef) HAL_SPI_TransmitReceive((SPI_HandleTypeDef*)priv_data->private_data,
															pTxData,
															pRxData,
															Size,
															Timeout);
	return status;
}

spi_t spi1 = {
	"spi1",
	&hspi1,
	TxData,
	RxData,
	stm32_ads8866_spi_init,
	stm32_ads8866_spi_transmit,
	stm32_ads8866_spi_receive,
	stm32_ads8866_spi_transmit_and_receive
};
//spi_t spi2 = {
//	"spi2",
//	&hspi2,
//	TxData,
//	RxData,
//	stm32_ads8866_spi_init,
//	stm32_ads8866_spi_transmit,
//	stm32_ads8866_spi_receive,
//	stm32_ads8866_spi_transmit_and_receive
//};

#else

#endif //USE_HARD_SPI

//SPI_HandleTypeDef hspi; 

uint16_t ADS8866_Read(void)
{
	uint16_t data = 0;
	uint8_t tx_data[2] = {ADS8866_CMD_CONVERT, 0xff}; // 发送命令和空字节以接收数据
	uint8_t rx_data[2] = {0};
	
	// 拉低片选引脚以选择ADS8866
	HAL_GPIO_WritePin(ADS8866_CS_GPIO_Port, ADS8866_CS_Pin, GPIO_PIN_RESET);
	
	// 发送命令并接收数据
	HAL_SPI_TransmitReceive(&hspi1, tx_data, rx_data, 2, 0xFF);
	
	// 拉高片选引脚以取消选择ADS8866
	HAL_GPIO_WritePin(ADS8866_CS_GPIO_Port, ADS8866_CS_Pin, GPIO_PIN_SET);
	
	// 合并接收到的数据
	data = (rx_data[0] << 8) | rx_data[1];
	
	return data;
}
#endif

uint8_t ads8866_rx_buf[ADS8866_DATANUM] = {0};
uint8_t ads8866_tx_buf[ADS8866_DATANUM] = {ADS8866_CONVERT, ADS8866_CONVERT};

spi_dev_t spi1 = 
{
	.io = 
	{
		{"ADS8866_SPI_CS1",SPI_CS,ADS8866_CS1_PORT,ADS8866_CS1_PIN,stm32_pin_init,stm32_pin_set,stm32_pin_reset,stm32_pin_read},
		{"ADS8866_SPI_CLK",SPI_CLK,ADS8866_CLK_PORT,ADS8866_CLK_PIN,stm32_pin_init,stm32_pin_set,stm32_pin_reset,stm32_pin_read},
		{"ADS8866_SPI_MOSI2",SPI_MOSI,ADS8866_MOSI1_PORT,ADS8866_MOSI1_PIN,stm32_pin_init,stm32_pin_set,stm32_pin_reset,stm32_pin_read},
		{"ADS8866_SPI_MISO",SPI_MISO,ADS8866_MISO_PORT,ADS8866_MISO_PIN,stm32_pin_init,stm32_pin_set,stm32_pin_reset,stm32_pin_read},
	},
	.transmit_and_receive = swap
};
spi_dev_t spi2 = 
{
	.io = 
	{
		{"ADS8866_SPI_CS2",SPI_CS,ADS8866_CS2_PORT,ADS8866_CS2_PIN,stm32_pin_init,stm32_pin_set,stm32_pin_reset,stm32_pin_read},
		{"ADS8866_SPI_CLK",SPI_CLK,ADS8866_CLK_PORT,ADS8866_CLK_PIN,stm32_pin_init,stm32_pin_set,stm32_pin_reset,stm32_pin_read},
		{"ADS8866_SPI_MOSI2",SPI_MOSI,ADS8866_MOSI2_PORT,ADS8866_MOSI2_PIN,stm32_pin_init,stm32_pin_set,stm32_pin_reset,stm32_pin_read},
		{"ADS8866_SPI_MISO",SPI_MISO,ADS8866_MISO_PORT,ADS8866_MISO_PIN,stm32_pin_init,stm32_pin_set,stm32_pin_reset,stm32_pin_read},
	},
	.transmit_and_receive = swap
};
cs_t current_senser_cs = 
{
	.port = CURRENT_CS_PORT,
	.pin = CURRENT_CS_PIN
};

cs_t voltage_senser_cs = 
{
	.port = VOLTAGE_CS_PORT,
	.pin = VOLTAGE_CS_PIN
};

ads8866_t current_senser = 
{
	.cs = &current_senser_cs,
	.name = "current value",
	.RxData = ads8866_rx_buf,
	.read = ads8866_read
};

ads8866_t voltage_senser = 
{
	.cs = &voltage_senser_cs,
	.name = "voltage value",
	.RxData = ads8866_rx_buf,
	.read = ads8866_read
};
#if (SPI_HARD == 1)
void ads8866_read(struct ads8866* pthis)
{
	//拉低片选
	HAL_GPIO_WritePin(pthis->cs->port,pthis->cs->pin,GPIO_PIN_RESET);
	//交换数据
	while(HAL_OK != HAL_SPI_TransmitReceive(&hspi1, ads8866_tx_buf, pthis->RxData, (uint16_t)ADS8866_DATANUM, 0xff));
	//拉高片选
	HAL_GPIO_WritePin(pthis->cs->port,pthis->cs->pin,GPIO_PIN_SET);
}
#endif
#if (SPI_SOFT == 1)
void ads8866_read(struct ads8866* pthis)
{
	//拉低片选
	HAL_GPIO_WritePin(pthis->cs->port,pthis->cs->pin,GPIO_PIN_RESET);
	//交换数据
//	if(pthis->)
	//拉高片选
	HAL_GPIO_WritePin(pthis->cs->port,pthis->cs->pin,GPIO_PIN_SET);
}
#endif

//// 定义ADS8866的引脚
//#define ADS8866_CS_PIN    GPIO_PIN_7
//#define ADS8866_CS_PORT   GPIOA
//#define ADS8866_SCLK_PIN  GPIO_PIN_5
//#define ADS8866_SCLK_PORT GPIOA
//#define ADS8866_MOSI_PIN  GPIO_PIN_1
//#define ADS8866_MOSI_PORT GPIOB
//#define ADS8866_MISO_PIN  GPIO_PIN_6
//#define ADS8866_MISO_PORT GPIOA

//// ADS8866命令定义
//#define ADS8866_WAKEUP    0x00
//#define ADS8866_SLEEP     0x02
//#define ADS8866_SYNC      0x04
//#define ADS8866_RESET     0x06
//#define ADS8866_NOP       0x08
//#define ADS8866_RDATA     0x12

//// helper宏定义
//#define ADS8866_CS_LOW()   HAL_GPIO_WritePin(ADS8866_CS_PORT, ADS8866_CS_PIN, GPIO_PIN_RESET)
//#define ADS8866_CS_HIGH()  HAL_GPIO_WritePin(ADS8866_CS_PORT, ADS8866_CS_PIN, GPIO_PIN_SET)
//#define ADS8866_SCLK_LOW() HAL_GPIO_WritePin(ADS8866_SCLK_PORT, ADS8866_SCLK_PIN, GPIO_PIN_RESET)
//#define ADS8866_SCLK_HIGH() HAL_GPIO_WritePin(ADS8866_SCLK_PORT, ADS8866_SCLK_PIN, GPIO_PIN_SET)
//#define ADS8866_MOSI_LOW() HAL_GPIO_WritePin(ADS8866_MOSI_PORT, ADS8866_MOSI_PIN, GPIO_PIN_RESET)
//#define ADS8866_MOSI_HIGH() HAL_GPIO_WritePin(ADS8866_MOSI_PORT, ADS8866_MOSI_PIN, GPIO_PIN_SET)
//#define ADS8866_MISO_READ() HAL_GPIO_ReadPin(ADS8866_MISO_PORT, ADS8866_MISO_PIN)

//// 初始化ADS8866的GPIO引脚
//void ADS8866_InitGPIO(void) {
//    __HAL_RCC_GPIOA_CLK_ENABLE(); // 使能GPIOA时钟
//	__HAL_RCC_GPIOB_CLK_ENABLE(); // 使能GPIOA时钟

//    GPIO_InitTypeDef GPIO_InitStruct = {0};

//    // CS引脚
//    GPIO_InitStruct.Pin = ADS8866_CS_PIN;
//    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出
//    GPIO_InitStruct.Pull = GPIO_NOPULL;
//    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
//    HAL_GPIO_Init(ADS8866_CS_PORT, &GPIO_InitStruct);

//    // SCLK引脚
//    GPIO_InitStruct.Pin = ADS8866_SCLK_PIN;
//    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出
//    GPIO_InitStruct.Pull = GPIO_NOPULL;
//    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
//    HAL_GPIO_Init(ADS8866_SCLK_PORT, &GPIO_InitStruct);

//    // MOSI引脚
//    GPIO_InitStruct.Pin = ADS8866_MOSI_PIN;
//    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出
//    GPIO_InitStruct.Pull = GPIO_NOPULL;
//    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
//    HAL_GPIO_Init(ADS8866_MOSI_PORT, &GPIO_InitStruct);

//    // MISO引脚
//    GPIO_InitStruct.Pin = ADS8866_MISO_PIN;
//    GPIO_InitStruct.Mode = GPIO_MODE_INPUT; // 输入
//    GPIO_InitStruct.Pull = GPIO_NOPULL;
//    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
//    HAL_GPIO_Init(ADS8866_MISO_PORT, &GPIO_InitStruct);

//    ADS8866_CS_HIGH(); // 初始状态下不选中ADS8866
//}

//// 模拟SPI发送一个字节
//void ADS8866_SPI_SendByte(uint8_t data) {
//    for (int i = 0; i < 8; i++) {
//        ADS8866_SCLK_LOW(); // 拉低时钟线

//        // 根据数据位设置数据线电平
//        if (data & 0x80) {
//            ADS8866_MOSI_HIGH();
//        } else {
//            ADS8866_MOSI_LOW();
//        }
//        data <<= 1; // 左移数据，准备发送下一位

//        ADS8866_SCLK_HIGH(); // 拉高时钟线，完成一位数据发送
//    }
//}

//// 模拟SPI接收一个字节
//uint8_t ADS8866_SPI_ReceiveByte(void) {
//    uint8_t data = 0;

//    // 读取MISO上的数据，同时提供时钟信号
//    for (int i = 0; i < 8; i++) {
//        ADS8866_SCLK_LOW(); // 拉低时钟线，准备读取数据
//        data <<= 1; // 左移数据位，准备接收新的数据位
//        if (ADS8866_MISO_READ()) {
//            data |= 0x01; // 如果MISO为高，则将当前位设置为1
//        }
//        ADS8866_SCLK_HIGH(); // 拉高时钟线，完成一位数据接收
//    }

//    return data;
//}

//// 发送命令并接收数据
//uint16_t ADS8866_SendCommand(uint8_t cmd) {
//    ADS8866_CS_LOW(); // 选中ADS8866
//	ADS8866_CS_HIGH();
//	DelayMicroseconds(3);
//	ADS8866_CS_LOW();
//    ADS8866_SPI_SendByte(cmd); // 发送命令

//    // 假设ADS8866需要额外两个时钟周期来准备数据
//    ADS8866_SCLK_LOW();
//    ADS8866_SCLK_HIGH();
//    ADS8866_SCLK_LOW();
//    ADS8866_SCLK_HIGH();

//    uint8_t highByte = ADS8866_SPI_ReceiveByte(); // 读取高8位数据
//    uint8_t lowByte = ADS8866_SPI_ReceiveByte(); // 读取低8位数据

//    ADS8866_CS_HIGH(); // 取消选中ADS8866

//    return ((uint16_t)highByte << 8) | lowByte; // 合并高低8位数据
//}

//// 读取ADS8866的转换数据
//uint16_t ADS8866_ReadData(void) {
////	ADS8866_CS_LOW();
////	ADS8866_CS_HIGH();
////	DelayMicroseconds(3);
////    return ADS8866_SendCommand(0xff);
//	
//	uint16_t data = 0x0000;
//	ADS8866_CS_LOW();
////	DelayMicroseconds(1);
//	ADS8866_MOSI_HIGH();
//	ADS8866_CS_HIGH();
////	DelayMicroseconds(3);
//	ADS8866_SCLK_LOW();
//	
//	ADS8866_CS_LOW();//CS下降沿，开始读取16位转换值
//	for(uint8_t i=0;i<16;i++)
//	{
//		data <<=1;
//		ADS8866_SCLK_HIGH();
//		if(ADS8866_MISO_READ() == 1)
//		{
//			data ++;
//		}
//		ADS8866_SCLK_LOW();
//	}
//	ADS8866_CS_HIGH();
//	return data;
//}



//定义ads8866通讯类型
typedef enum
{
	three_line,
	four_line,
	daisy_chain
}ads8866_interface_mode;

typedef enum
{
	spi_hard,
	spi_soft
}ads8866_com_mode;

typedef struct _io
{
	GPIO_TypeDef *port;
	uint16_t pin;
}io_t;

typedef struct ads8866_io
{
	io_t cs;
	io_t clk;
	io_t mosi;
	io_t miso;
}ads8866_io_pin;

typedef struct ads8866_device
{
	const char* device_name;						//设备名称
	uint16_t rx_val;						//接收数据的值
	ads8866_interface_mode interface_mode;//与主机连接模式
	ads8866_com_mode com_mode;//与主机的通讯模式
	ads8866_io_pin* io;
	ADS8866_Status (*init)(struct ads8866_device* dev);				//设备初始化函数
	ADS8866_Status (*read)(struct ads8866_device* dev);				//读取数据函数
}ads8866_dev_t;

ADS8866_Status ads8866_init(struct ads8866_device* dev)
{
	
	//初始化通信接口
	if(dev->com_mode == spi_soft)
	{
		
	}
	//
}

ADS8866_Status read_data(struct ads8866_device* dev)
{
	if(dev->com_mode == spi_soft)
	{
		if(dev->interface_mode == three_line)
		{
			//开始转化
			HAL_GPIO_WritePin(dev->io->cs.port,dev->io->cs.pin,GPIO_PIN_RESET);
			HAL_GPIO_WritePin(dev->io->mosi.port,dev->io->mosi.pin,GPIO_PIN_SET);
			HAL_GPIO_WritePin(dev->io->cs.port,dev->io->cs.pin,GPIO_PIN_SET);	
			
			HAL_GPIO_WritePin(dev->io->clk.port,dev->io->clk.pin,GPIO_PIN_RESET);
			HAL_GPIO_WritePin(dev->io->cs.port,dev->io->cs.pin,GPIO_PIN_RESET);
			for(uint8_t i = 0; i < (16); i++)
			{
				HAL_GPIO_WritePin(dev->io->clk.port,dev->io->clk.pin,GPIO_PIN_SET);
				HAL_GPIO_WritePin(dev->io->clk.port,dev->io->clk.pin,GPIO_PIN_RESET);
				if(HAL_GPIO_ReadPin(dev->io->miso.port,dev->io->miso.pin))
				{
					dev->rx_val |= (0x01 << (15-i));
				}
				else
				{
					dev->rx_val &= ~(0x01 << (15-i));
				}
			}
			HAL_GPIO_WritePin(dev->io->cs.port,dev->io->cs.pin,GPIO_PIN_SET);
		}
	}
}



ads8866_io_pin current_io = 
{
	.cs = {ADS8866_CS1_PORT, ADS8866_CS1_PIN},
	.clk = {ADS8866_CLK_PORT, ADS8866_CLK_PIN},
	.mosi = {ADS8866_MOSI1_PORT, ADS8866_MOSI1_PIN},
	.miso = {ADS8866_MISO_PORT, ADS8866_MISO_PIN}
};
ads8866_io_pin voltage_io = 
{
	.cs = {ADS8866_CS2_PORT, ADS8866_CS2_PIN},
	.clk = {ADS8866_CLK_PORT, ADS8866_CLK_PIN},
	.mosi = {ADS8866_MOSI2_PORT, ADS8866_MOSI2_PIN},
	.miso = {ADS8866_MISO_PORT, ADS8866_MISO_PIN}
};

ads8866_dev_t current = 
{
	.device_name = "current",						//设备名称
	.rx_val = 0,						//接收数据的值
	.interface_mode = three_line,//与主机连接模式
	.com_mode = spi_soft,//与主机的通讯模式
	.io = &current_io,
	.init = ads8866_init,				//设备初始化函数
	.read= read_data				//读取数据函数
};
ads8866_dev_t voltage = 
{
	.device_name = "voltage",		//设备名称
	.rx_val = 0,					//接收数据的值
	.interface_mode = three_line,	//与主机连接模式
	.com_mode = spi_soft,			//与主机的通讯模式
	.io = &voltage_io,
	.init = ads8866_init,			//设备初始化函数
	.read= read_data				//读取数据函数
};

void test(void)
{
	while(1)
	{
		printf("---------------------\r\n");
		current.read(&current);
		printf("current:%f\r\n",(current.rx_val*2.5/65535)/2.0);
		printf("---------------------\r\n");
		voltage.read(&voltage);
		printf("voltage:%f\r\n",(voltage.rx_val*2.5/65535)/2.0);
//		float vol = 0.0f;
//		for(uint8_t i = 0; i < 10; i++)
//		{
//			voltage.read(&voltage);
//			vol += ((voltage.rx_val*2.5/65535)/2.0);
//		}
//		vol = vol / 10.0;
//		printf("voltage:%f\r\n",vol);
//		vol = 0.0f;
		HAL_Delay(1000);
	}
}


